/**
 * @file CLambdaAlg.hpp Deklarácia triedy CLambdaAlg.
 *
 * @author Martin Kosorinský.
 * @date 1.4.2009.
 */

#ifndef CLAMBDAALG_HEADER
#define CLAMBDAALG_HEADER

#include "CRhoAlgCommon.hpp"

/**
 * @brief Trieda zapúzdrujúca vyhľadávanie diskrétneho logaritmu metódou Pollard-Lambda.
 * Trieda zapúzdruje metódy a dátové prvky potrebné pri výpočte diskrétneho logaritmu
 * v grupe bodov eliptickej krivky. Využíva algoritmus známy pod menom Pollard-Lambda.
 * @warning Implementácia nie je bezpečná pre paralelné výpočty pomocou vlákien, keďže
 * operácie z dôvodu optimalizácie využívajú statické dátové štruktúry.
 */
class CLambdaAlg : public CECContext {
public:
    /**
     * @brief Hlavná metóda spúšťajúca výpočet diskrétneho logaritmu.
     * Metóda pracuje na základe vopred inicializovaných nastavení nadradenej triedy CECContext, medzi
     * ktoré patria parametre krivky ako aj bod, ktorého diskrétny logaritmus hľadáme.
     * @param[out] vysledok Premenná typu big, do ktorej bude uložený výsledok v prípade úspechy výpočtu.
     * Pamäť musí byť vopred alokovaná!
     * @warning V prípade neúspechu výpočtu obsahuje premenná @a vysledok nedefinovanú hodnotu.
     * @warning Funkcia nie je thread safe.
     * @return Vráti TRUE v prípade úspechu výpočtu, v opačnom prípade vráti FALSE.
     */
    static bool computeLogarithm(big vysledok);
    /**
     * @brief Inicializátor statických parametrov výpočtu.
     * Ak parametre nebudú špecifikované (budú mať defaultnú hodnotu NULL), tak bude parameter A nastavený
     * na 0 a horná hranica prehľadávaného intervalu B bude mať hodnotu <i>ord - 1</i>, kde ord je rád grupy.
     * @param[in] a Hodnota, na ktorú bude inicializovaný parameter A (dolná hranica intervalu), ak a != NULL.
     * @param[in] b Hodnota, na ktorú bude inicializovaný parameter B (horná hranica intervalu), ak b != NULL.
     */
    static void setLambdaParams(const big a = NULL, const big b = NULL);
    /**
     * @brief Dealokátor statických parametrov výpočtu algoritmu Pollard-Lambda.
     * Zabezpečí korektnú dealokáciu statických dátových položiek, v prípade že ich hodnota nie je NULL.
     * Parametre sú po dealokovaní nastavené na NULL.
     */
    static void freeLambdaParams();
protected:
    /**
     * @brief Dolná hranica prehľadávaného intervalu.
     * Alokáciu a nastavenie hodnôt zabezpečuje interne procedúra computeLogarithm().
     */
    static big paramA;
    /**
     * @brief Horná hranica prehľadávaného intervalu.
     * Alokáciu a nastavenie hodnôt zabezpečuje interne procedúra computeLogarithm().
     */
    static big paramB;
    /**
     * @brief Limit, na základe ktorého bude počítaný hash z bodov.
     * Nadobúdané hodnoty hashovacej funkcie budú z intervalu <1,stepLimit>.
     */
    static big stepLimit;
    /**
     * @brief Funkcia, ktorá zabezpečuje výpočet dĺžky najbližšieho skoku.
     * Funkcia deterministicky na základe aktuálneho stavu (bodu @a P) vypočíta
     * dĺžku skoku pre potreby funkcie #makeStep.
     * @see makeStep().
     * @param[in] P je bod na eliptickej krivke, na základe ktorého počítame skok.
     * @param[out] stepSize bude po skončení funkcie obsahovať veľkosť skoku pre bod @a P.
     * @warning Funkcia nie je thread safe.
     */
    static inline void getStepSize(const epoint * P, big stepSize);
    /**
     * @brief Procedúra vykonávajúca skok "kengury".
     * Procedúra vykoná skok zo zadaného bodu a na základe neho upraví ubehnutú vzdialenosť.
     * Skok je vypočítaný na základe pomocnej funkcie getStepSize a vstupného bodu @a P.
     * @see getStepSize().
     * @param[in,out] P je vstupno-výstupný parameter reprezentujúci bod na eliptickej krivke, z ktorého skáčeme.
     * @param[in,out] dm je celková ubehnutá vzdialenosť typu big.
     * @warning Funkcia nie je thread safe.
     */
    static inline void makeStep(epoint * P, big dm);
};

#endif /* CLAMBDAALG_HEADER */

